package com.beardedcoder.lowPower.storage;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OptionalDataException;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;

import com.beardedcoder.lowPower.R;
import com.beardedcoder.lowPower.model.HomeScreenCellData;
import com.beardedcoder.utils.UtilObjectSerialiser;

public class StorageHomeScreen {
	/**
	 * file storage name
	 */
	private static final String FILE_STORAGE = "HOME_SCREEN_STORAGE_ORDER";
	
	/**
	 * These strings are used both as the descriptor text and as
	 * the identifier to couple the loading of the correct PowerFeature interface
	 * to the correct view when loading into the listView in ActivityHomeScreen
	 */
	public static final String DESCRIPTION_AIRPLANE = "Airplane";
	public static final String DESCRIPTION_WIFI = "Wifi";
	public static final String DESCRIPTION_BLUETOOTH = "Bluetooth";
	public static final String DESCRIPTION_GPS = "GPS";
	public static final String DESCRIPTION_BRIGHTNESS_AUTO_ADJUST = "Auto Brightness";
	
	private static int STANDARD_LIST_SIZE = 5;
	private static ArrayList<HomeScreenCellData> standardLayout;
	
	private ArrayList<HomeScreenCellData> data = null;
	private boolean unsavedChanges = false;

	private static boolean forceOverwriteStorageOptions = false;
	
	@SuppressWarnings("unchecked")
	public StorageHomeScreen (Context context) {
		if (standardLayout == null) {
			loadDefaultValues();
		} else if (standardLayout.size() != STANDARD_LIST_SIZE) {
			loadDefaultValues();
		}
		
		try {
			FileInputStream file = context.openFileInput(FILE_STORAGE);
			data = (ArrayList<HomeScreenCellData>) UtilObjectSerialiser.read(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (StreamCorruptedException e) {
			e.printStackTrace();
		} catch (OptionalDataException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		if (data == null) {
			data = new ArrayList<HomeScreenCellData> (standardLayout);
			unsavedChanges = true;
		} else if (data.size() != STANDARD_LIST_SIZE || forceOverwriteStorageOptions  == true) {
			// the size we have in storage does not equal the 
			// new size, therefore there are new options. 
			if (forceOverwriteStorageOptions  == true) {
				data = new ArrayList<HomeScreenCellData> (standardLayout);
				unsavedChanges = true;
				return;
			} else {
				// we simply add new elements at the end. 
				for (int i = data.size() ; i < standardLayout.size() ; i ++) {
					data.add(standardLayout.get(i));
				}
			}
		}
	}

	/**
	 * This method is called to initialise the standardLayout list. 
	 * This is used as the basic setup and is loaded or not when an instance of
	 * this class is constructed. 
	 * If the STANDARD_LIST_SIZE static field is not equal to the size of 
	 * this arrayList, then it will be re-initialised. 
	 */
	private void loadDefaultValues() {
		standardLayout = new ArrayList<HomeScreenCellData>();
		standardLayout.add(new HomeScreenCellData(R.drawable.ic_action_airplane, DESCRIPTION_AIRPLANE));
		standardLayout.add(new HomeScreenCellData(R.drawable.ic_action_wifi, DESCRIPTION_WIFI));
		standardLayout.add(new HomeScreenCellData(R.drawable.ic_action_bluetooth, DESCRIPTION_BLUETOOTH));
		standardLayout.add(new HomeScreenCellData(R.drawable.ic_action_gps, DESCRIPTION_GPS));
		standardLayout.add(new HomeScreenCellData(R.drawable.ic_action_setting, DESCRIPTION_BRIGHTNESS_AUTO_ADJUST));
	}
	
	public ArrayList<HomeScreenCellData> getOrder() {
		return data;
	}
	
	public void setOrder(ArrayList<HomeScreenCellData> newOrder) {
		data = newOrder;
		unsavedChanges = true;
	}
	
	/**
	 * This requires a context to save (because of writing to file system) 
	 * We don't persist a context here because holding context in a variable is not advised
	 * it usually causes leak, therefore this will save if any changes are unsaved
	 * they will be persisted. 
	 * @param context
	 */
	public void save (Context context) {
		if (unsavedChanges) {
			try {
				UtilObjectSerialiser.write(data, context.openFileOutput(FILE_STORAGE, Context.MODE_PRIVATE));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
